#ifndef _RELIABLE_
#define _RELIABLE_

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/select.h>
#include <netinet/in.h> 
#include <netdb.h>
#include <errno.h>

/* 
 * some define of constant variables
 */

//PORT OF SERVER 
#define SERV_PORT    10080

//port of client
#define CLI_PORT	 10080

//packet size
#define PACK_SIZE    1024

//size of header for message type
#define MSG_HEAD_SIZE 15

#define WIN_SIZE     4

//size of buffer for reading file data 
#define BUF_MSGS_SIZE     WIN_SIZE * (PACK_SIZE - MSG_HEAD_SIZE)

//size of buffer for sending message
#define BUF_SEND_SIZE	  PACK_SIZE

//size of buffer for receiving message from server
#define BUF_RECV_SIZE	  5

//#define MAX_MESS_LEN BUF_SIZE_SEND


#define SOCK_ADDR struct sockaddr


/*
 * definition of some types of message header struct
 */
typedef struct {		//header of message
	char msg_type;
	int seq_num;
	long ip;			//long is 4 bytes in ugrad machine
	unsigned short port;//unsigned short is 2 bytes
	int len;			//header length
} MSG_HEAD;


typedef struct {		//response message, ACK or NACK
	char msg_type;		// value is either "ACK" or "NACK"
	int seq_num;
} ECHO;

typedef struct {		//message that initial a connection or close a connection 
	char msg_type;		//value is either "START" or "END"
} GREET;

/*
 * definition of queue list
 */

typedef struct node {		// # of nodes in the queue is the same as window size. 
	int offset;			// offset of node in the queue.
	struct node *next;  // pointer to the next node. if it is set to zero, it means that the current node is the end of the queue.
} NODE;
 
/*
 * function to do actions over queue list
 */

int pop(NODE *q_head) //pop up the head node of the queue, and return the value of offset in the head node
{
	int result = q_head->offset;
	if(q_head->next)
		q_head = q_head->next;
	return result;	 
}

void push(NODE *q_end, NODE *in_node) //push new node (in_node) to the end of queue
{
	q_end->next = in_code;
	q_end = q_end->next;	
}

#endif
